//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/**
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Abstract: Code specific to the PASSWD CPL
**/

#include "cplpch.h"

//[HKEY_LOCAL_MACHINE\Comm\Security\LASSD\AE\{1B38A686-7CDC-4017-A5E9-4C6A9DD7E5BA}]
const LPWSTR szRegKeyAESystemStartup = TEXT("Comm\\Security\\LASSD\\AE\\{1B38A686-7CDC-4017-A5E9-4C6A9DD7E5BA}");
const LPWSTR szRegValueAEFrequency = TEXT("AEFrequencyValue");

BOOL fScreenSaverPasswordEnabled;
BOOL fSystemStartupPasswordEnabled;

void GetRegSettings()
{
   DWORD dwSize;
   DWORD dwType;
   DWORD dwValue;
   LONG  lResult;
   HKEY  hkey;

   fSystemStartupPasswordEnabled = FALSE;

   lResult =
      RegOpenKeyEx(
          HKEY_LOCAL_MACHINE,
          szRegKeyAESystemStartup,
          NULL,
          KEY_READ,
          &hkey
          );

   if (lResult == ERROR_SUCCESS) 
   {
	   dwSize  = sizeof(dwValue);
	   RegQueryValueEx(hkey, szRegValueAEFrequency, NULL, &dwType, (PBYTE)&dwValue, &dwSize); 

	
	   RegCloseKey(hkey);

	   if ( dwValue != 0xFFFFFFFF )
	   {
		   fSystemStartupPasswordEnabled = TRUE;		
	   }
   }

   return;
}
    

void SaveRegSettings()
{
   LONG  lResult;
   HKEY  hkey;
   DWORD dwValue = 0;

   if ( fSystemStartupPasswordEnabled == FALSE)
   {
		dwValue = 0xFFFFFFFF;
   }

	lResult =
      RegOpenKeyEx(
          HKEY_LOCAL_MACHINE,
          szRegKeyAESystemStartup,
          NULL,
          KEY_WRITE,
          &hkey
          );

    if ( lResult == ERROR_SUCCESS )
	{
		RegSetValueEx(hkey, szRegValueAEFrequency, NULL, REG_DWORD,(PBYTE)&dwValue, sizeof(dwValue));
		RegCloseKey(hkey);
	}

	return;
}

void EnablePwdCheckbox(HWND hDlg)
{
	TCHAR sz1[PASSWORD_LENGTH+2], sz2[PASSWORD_LENGTH+1];
	
	GetDlgItemText(hDlg, IDC_EDIT_NEW_PASS, sz1, PASSWORD_LENGTH+1);
	GetDlgItemText(hDlg, IDC_EDIT_CONF_PASS, sz2, PASSWORD_LENGTH+1);
	
    if (*sz1 && *sz2 && 0==_tcsicmp(sz1, sz2)) 
	{
		EnableWindow(DI(IDC_CHK_PASSWRD), TRUE);
		EnableWindow(DI(IDC_CHK_PASSWRDSCREENSAVER), TRUE);

		if ( fSystemStartupPasswordEnabled )
		{
			CheckDlgButton(hDlg,IDC_CHK_PASSWRD,BST_CHECKED);
		} else {
			CheckDlgButton(hDlg,IDC_CHK_PASSWRD,BST_UNCHECKED);
		}

		if ( fScreenSaverPasswordEnabled )
		{
			CheckDlgButton(hDlg,IDC_CHK_PASSWRDSCREENSAVER,BST_CHECKED);
		} else {
			CheckDlgButton(hDlg,IDC_CHK_PASSWRDSCREENSAVER,BST_UNCHECKED);
		}

	} else 	{
		fSystemStartupPasswordEnabled = FALSE;
		fScreenSaverPasswordEnabled   = FALSE;

		CheckDlgButton(hDlg,IDC_CHK_PASSWRD,BST_UNCHECKED);
		CheckDlgButton(hDlg,IDC_CHK_PASSWRDSCREENSAVER,BST_UNCHECKED);

		EnableWindow(DI(IDC_CHK_PASSWRD), FALSE);
		EnableWindow(DI(IDC_CHK_PASSWRDSCREENSAVER), FALSE);
	}
}


extern "C" BOOL APIENTRY PasswdDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
	static BOOL fEditsAreUntouched;
	static LPTSTR pszOldPass;
	
    switch (message)
	{
   	case WM_INITDIALOG:
		// in our case, lParam is the password
		ASSERT(lParam);
		pszOldPass = (LPTSTR)lParam;
    	Edit_LimitText(DI(IDC_EDIT_NEW_PASS), PASSWORD_LENGTH);
    	Edit_LimitText(DI(IDC_EDIT_CONF_PASS), PASSWORD_LENGTH);
        SetDlgItemText(hDlg, IDC_EDIT_NEW_PASS, pszOldPass);
        SetDlgItemText(hDlg, IDC_EDIT_CONF_PASS,pszOldPass);
		SetFocus(DI(IDC_EDIT_NEW_PASS));
		Edit_SetSel(DI(IDC_EDIT_NEW_PASS), 0, -1);

		GetRegSettings();

		fScreenSaverPasswordEnabled = GetPasswordStatus() & PASSWORD_STATUS_SCREENSAVERPROTECT;

		EnablePwdCheckbox(hDlg);

        AygInitDialog( hDlg, SHIDIF_SIPDOWN );

		fEditsAreUntouched = TRUE;
		return 0; // dont let gwe change focus
		
			
	case WM_COMMAND:
    	switch (LOWORD(wParam))
        {
        case IDC_EDIT_NEW_PASS:
        case IDC_EDIT_CONF_PASS:
        	// The first time they hit eitehr edit control, clear the other 
            if(HIWORD(wParam)==EN_CHANGE)
            {
            	if(fEditsAreUntouched)
                {
	            	fEditsAreUntouched = FALSE;
					SetDlgItemText(hDlg, (LOWORD(wParam)==IDC_EDIT_NEW_PASS ? 
									IDC_EDIT_CONF_PASS : IDC_EDIT_NEW_PASS), EMPTY_STRING);
				}
				EnablePwdCheckbox(hDlg);
			}
			return TRUE;

			case IDC_CHK_PASSWRD:
				fSystemStartupPasswordEnabled = IsDlgButtonChecked(hDlg,IDC_CHK_PASSWRD) == BST_CHECKED;
				break;

			case IDC_CHK_PASSWRDSCREENSAVER:
				fScreenSaverPasswordEnabled = IsDlgButtonChecked(hDlg,IDC_CHK_PASSWRDSCREENSAVER) == BST_CHECKED;
				break;

		case IDOK:
		 {
			TCHAR sz1[PASSWORD_LENGTH+2], sz2[PASSWORD_LENGTH+1];
			BOOL fSet;
			DWORD dwStatus;

			GetDlgItemText(hDlg, IDC_EDIT_NEW_PASS, sz1, PASSWORD_LENGTH+1);
			GetDlgItemText(hDlg, IDC_EDIT_CONF_PASS, sz2, PASSWORD_LENGTH+1);
					
            if(wcsicmp(sz1, sz2))
            {
            	MessageBox(hDlg, CELOADSZ(IDS_PASSWDERR_NOTMATCH), CELOADSZ(IDS_PASSWDERR_TITLE), MB_ICONINFORMATION | MB_OK );
                SetFocus(GetDlgItem(hDlg, IDC_EDIT_CONF_PASS));
                Edit_SetSel(DI(IDC_EDIT_CONF_PASS), 0L, -1);   
                return FALSE;
			}
                    
			//
			// NOTE: The Control Panels & the StartUI & Welcome dialogs all force passwds to
			// lowercase so as to be case-insensitive, despite the fact that the underlying
			// OS password APIs are case sensitive.
			//
			_wcslwr(sz1);

            fSet = SetPassword(CheckPassword(NULL) ? NULL : pszOldPass, sz1);
            ASSERT(fSet);

            //dwStatus = (fSet && Button_GetCheck(DI(IDC_CHK_PASSWRD))) ? PASSWORD_STATUS_ACTIVE : 0;

			if ( _tcslen(sz1) != 0)
			{
				dwStatus = PASSWORD_STATUS_ACTIVE;
			} else {
				dwStatus = 0;
			}

            if (dwStatus)
			{
               dwStatus |= (fSet && Button_GetCheck(DI(IDC_CHK_PASSWRDSCREENSAVER))) ? PASSWORD_STATUS_SCREENSAVERPROTECT : 0;
			}


            fSet = SetPasswordStatus(dwStatus, sz1);

            ASSERT(fSet);
            if (fSet)
            {
				SaveRegSettings();

                WCHAR szUserName[128];
                DWORD cchUser = ARRAYSIZEOF(szUserName);
                if (GetUserNameExW(NameWindowsCeLocal, szUserName, &cchUser ))
                {
                    // set the user secret used for CryptProtectData APIs only if power on password is checked
                    // Since we don't store the password on the device, the user needs to provide it after a warm reset
                    // so as that SetCurrentUser can succeed.
                    if (dwStatus) 
                        SetUserData((PBYTE)sz1, (_tcslen(sz1))*sizeof(TCHAR));
                    else
                        SetUserData(NULL, 0);   // no password used for CryptProtectData
                }
            }
			
			return TRUE;
		  }
		}
	}
	return FALSE;                                           
}


